package com.ax.security;

import com.ax.entity.User;
import com.ax.mapper.UserMapper;
import com.ax.security.JwtUtil;
import com.ax.security.UserDetailsImpl;
import io.jsonwebtoken.Claims;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Autowired
    private UserMapper userMapper;

    // 定义需要放行的路径集合
    private static final List<String> EXCLUDE_PATHS = Arrays.asList(
            "/api/auth/admin/login",
            "/doc.html",
            "/swagger-ui.html"
    );
    @Override
    protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException {
        //提取并验证令牌格式
        //从 HTTP 请求头中获取名为 Authorization 的字段值
        //String token = request.getHeader("Authorization");
        String requestURI = request.getRequestURI();
        //验证令牌的合法性
        if (EXCLUDE_PATHS.stream().anyMatch(uri -> uri.equals(requestURI))) {
            filterChain.doFilter(request, response);
            return;
        }
        String token = request.getHeader("Authorization");
        if (!StringUtils.hasText(token) || !token.startsWith("Bearer ")) {
            filterChain.doFilter(request, response);
            return;
        }
        //去除令牌中的 Bearer 前缀，提取纯 JWT 字符串
        token = token.substring(7);
        //解析令牌
        String userid;
        try {
            Claims claims = JwtUtil.parseJWT(token);
            userid = claims.getSubject();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        User user = userMapper.getById((long) Integer.parseInt(userid));
        //验证用户是否存在
        if (user == null) {
            throw new RuntimeException("用户名未登录");
        }
        //封装用户权限信息
        UserDetailsImpl loginUser = new UserDetailsImpl(user);
        //设置认证上下文
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginUser, null, null);
        // 如果是有效的jwt，那么设置该用户为认证后的用户
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        // 继续执行过滤链
        filterChain.doFilter(request, response);
    }
}